import { IssueReport } from '../../model/Defects';

export enum DisableType {
    FILE = 0,
    LINE = 1
}

export class DisableUtil {
    private fileDisableText: RegExp = /\/\* homecheck-disable \*\//g;
    private nextLineDisableText: RegExp = /\/\/ homecheck-disable-next-line/g;
    private static disableInstance: DisableUtil;

    private constructor() {}

    public static getInstance(): DisableUtil {
        if (!this.disableInstance) {
            this.disableInstance = new DisableUtil();
        }
        return this.disableInstance;
    }

    public setDisableText(fileDisableRegExp: RegExp, nextLineDisableText: RegExp): void {
        this.fileDisableText = fileDisableRegExp;
        this.nextLineDisableText = nextLineDisableText;
    }

    public test(disableType: DisableType, content: string): boolean {
        if (disableType === DisableType.FILE) {
            this.fileDisableText.lastIndex = 0;
            return this.fileDisableText.test(content);
        }
        else if (disableType === DisableType.LINE) {
            this.nextLineDisableText.lastIndex = 0;
            return this.nextLineDisableText.test(content);
        }
        else {
            return false;
        }
    }

    public filterDisableIssue(lineList: string[], issues: IssueReport[]): IssueReport[] {
        let filtedIssues: IssueReport[] = [];
        issues.forEach(issue => {
            // 有些特殊规则允许返回行列号为0
            if (issue.defect.reportLine < 0 || issue.defect.reportLine - 1 > lineList.length) {
                return;
            }
            const text = lineList[issue.defect.reportLine - 2];
            if (!this.isDisableIssue(text, issue.defect.ruleId)) {
                filtedIssues.push(issue);
            }
        });
        return filtedIssues;
    }

    private isDisableIssue(lineText: string, ruleId: string): boolean {
        if (!lineText || lineText.length === 0) {
            return false;
        }

        if (lineText.includes(ruleId) && this.test(DisableType.LINE, lineText)) {
            return true;
        }
        return false;
    }
}